﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Data;
using MDSCommon;
using ComboBox = System.Windows.Controls.ComboBox;
using MessageBox = System.Windows.MessageBox;

namespace MDSAdministration
{
    /// <summary>
    /// Interaction logic for Connect.xaml
    /// </summary>
    public partial class ConnectWindow : Window
    {
        private bool txtServerAChanged = false;
        private bool txtServerBChanged = false;
        public List<string> Servers { get; set; }

        private ServerMDSDetails _ServerA;
        private ServerMDSDetails _ServerB;
        public ServerMDSDetails ServerA {
            get { return _ServerA; }
            set
            {
                _ServerA = value;
                if (value != null)
                {
                    ServerACurrent.ServerName = value.ServerName;
                    ServerACurrent.Database = value.Database;
                    ServerACurrent.Model = value.Model;
                    ServerACurrent.ModelVersion = value.ModelVersion;
                    ServerACurrent.schemaVersion = value.schemaVersion;
                }
            } }
        public ServerMDSDetails ServerB
        {
            get { return _ServerB; }
            set
            {
                _ServerB = value;
                if (value != null)
                {
                    ServerBCurrent.ServerName = value.ServerName;
                    ServerBCurrent.Database = value.Database;
                    ServerBCurrent.Model = value.Model;
                    ServerBCurrent.ModelVersion = value.ModelVersion;
                    ServerBCurrent.schemaVersion = value.schemaVersion;
                }  
            } }

        public ServerMDSDetails ServerACurrent { get; set; }
        public ServerMDSDetails ServerBCurrent { get; set; }

        private bool Loading = false;
        private bool isCancel = false;
        
        public ConnectWindow()
        {
            InitializeComponent();
            btnOk.IsDefault = true;
            btnCancel.IsCancel = true;

            Servers = new List<string>();
            cbxServerA.ItemsSource = ReadServerNamesFile();
            cbxServerB.ItemsSource = ReadServerNamesFile();

            ServerACurrent = new ServerMDSDetails();
            ServerBCurrent = new ServerMDSDetails();

        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            isCancel = true;
        }

        void CancelConnectionConfig()
        {
            ServerA.ServerName = ServerACurrent.ServerName;
            ServerA.Database = ServerACurrent.Database;
            ServerA.Model = ServerACurrent.Model;
            ServerA.ModelVersion = ServerACurrent.ModelVersion;
            ServerA.schemaVersion = ServerACurrent.schemaVersion;

            ServerB.ServerName = ServerBCurrent.ServerName;
            ServerB.Database = ServerBCurrent.Database;
            ServerB.Model = ServerBCurrent.Model;
            ServerB.ModelVersion = ServerBCurrent.ModelVersion;
            ServerB.schemaVersion = ServerBCurrent.schemaVersion;
        }
        private void btnOk_Click(object sender, RoutedEventArgs e)
        {
            if (String.IsNullOrEmpty(cbxServerA.Text) || String.IsNullOrEmpty(cbxServerB.Text))
            {
                e.Handled = false;
                MessageBox.Show("Server details are missing", "Warning", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            if (cbxDatabaseA.SelectedValue == null || cbxDatabaseB.SelectedValue == null ||
                String.IsNullOrEmpty(cbxDatabaseA.SelectedValue.ToString()) || String.IsNullOrEmpty(cbxDatabaseB.SelectedValue.ToString()))
            {
                e.Handled = false;
                MessageBox.Show("Database details are missing", "Warning", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            if (cbxModelA.SelectedValue == null || cbxModelB.SelectedValue == null ||
                String.IsNullOrEmpty(cbxModelA.SelectedValue.ToString()) || String.IsNullOrEmpty(cbxModelB.SelectedValue.ToString()))
            {
                e.Handled = false;
                MessageBox.Show("Model details are missing", "Warning", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            if (cbxVersionA.SelectedValue == null || cbxVersionB.SelectedValue == null ||
                String.IsNullOrEmpty(cbxVersionA.SelectedValue.ToString()) || String.IsNullOrEmpty(cbxVersionB.SelectedValue.ToString()))
            {
                e.Handled = false;
                MessageBox.Show("Version details are missing", "Warning", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            if (txtServerAChanged == true || txtServerBChanged == true)
            {
                e.Handled = false;

                if(txtServerAChanged == true)
                {
                    txtServerAChangedValidation();
                }

                if (txtServerBChanged == true)
                {
                    txtServerBChangedValidation();
                }

                MessageBox.Show("Invalid details have been selected", "Warning", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
            else
            {
                SaveServerNamesFile(ServerA.ServerName);
                SaveServerNamesFile(ServerB.ServerName);
                this.DialogResult = true;    
            }
        }

        private void SaveServerNamesFile(string serverName)
        {
            if (String.IsNullOrEmpty(Servers.Find(x => x.Contains(serverName))))
            {
                Servers.Add((serverName));
            }


            var fileName = ConfigurationManager.AppSettings["ServerNamesFile"];
            var filePath = ".\\" + fileName;
            using (StreamWriter w = new StreamWriter(filePath))
            {
                foreach (var server in Servers)
                {
                    w.WriteLine(server);
                }
            }
        }
        private List<string> ReadServerNamesFile()
        {
            
            var fileName = ConfigurationManager.AppSettings["ServerNamesFile"];
            var filePath = ".\\" + fileName;
            if (File.Exists(".\\" + fileName))
            {
                Servers.Clear();
                using (StreamReader r = new StreamReader(filePath))
                {
                    string line;
                    while ((line = r.ReadLine()) != null)
                    {
                        Servers.Add(line);
                    }
                }
            }

            return Servers;
        }
        private bool populateDatabase(string server, ComboBox cb)
        {
            try
            {
                if (String.IsNullOrEmpty(server))
                {
                    return false;
                }

                using (new WaitCursor())
                {
                    cb.DataContext = null;

                    DataSet ds = DataHelper.GetDatabases(server);

                    
                    if (ds != null && ds.Tables.Count > 0)
                    {
                        cb.DataContext = ds.Tables[0];
                        cb.DisplayMemberPath = Constants.DATABASE_NAME;
                        cb.SelectedValuePath = Constants.DATABASE_NAME;
                    }
                    else
                    {
                        MessageBox.Show("Could not find any MDS database/s. Check that you have permission.");
                        return false;
                    }
                }

            }
            catch (System.Exception ex)
            {
                Console.WriteLine("Error.");
                string m = ex.Message;
                MessageBox.Show("The server can not be found or you do not have sufficent rights to access the server", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            return true;
        }
        private void populateMode(string server, string database, ComboBox cb)
        {
            DataSet ds = DataHelper.GetModels(server, database);
            cb.DataContext = ds.Tables[0];
            cb.DisplayMemberPath = "Name";
            cb.SelectedValuePath = "Name";
        }
        private void populateVersion(string server, string database, string model, ComboBox cb)
        {
            DataSet ds = DataHelper.GetModelVersions(server, database, model);
            cb.DataContext = ds.Tables[0];
            cb.DisplayMemberPath = "Name";
            cb.SelectedValuePath = "Name";
        }

        private void cbxServerA_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (!String.IsNullOrEmpty(cbxServerA.Text) && Loading == false)
            {
                ServerA.ServerName = cbxServerA.Text;
                txtServerAChanged = true;
            }
            else
            {
                txtServerAChanged = false;
             }        
        }
        private void cbxServerB_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (!String.IsNullOrEmpty(cbxServerB.Text) && Loading == false)
            {
                ServerB.ServerName = cbxServerB.Text;
                txtServerBChanged = true;
            }
            else
            {
                txtServerBChanged = false;
            }
        }
 
        private void cbxDatabaseA_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbxDatabaseA.SelectedValue != null)
            {
                ServerA.Database = cbxDatabaseA.SelectedValue.ToString();

                cbxVersionA.DataContext = null;
                ServerA.ModelVersion = "";

                populateMode(cbxServerA.Text, cbxDatabaseA.SelectedValue.ToString(), cbxModelA);
            }
        }
        private void cbxModelA_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbxDatabaseA.SelectedValue != null && cbxModelA.SelectedValue != null)
            {
                ServerA.Model = cbxModelA.SelectedValue.ToString();
                populateVersion(cbxServerA.Text, cbxDatabaseA.SelectedValue.ToString(), cbxModelA.SelectedValue.ToString(),
                                cbxVersionA);
            }
        }
        private void cbxVersionA_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbxDatabaseA.SelectedValue != null && cbxModelA.SelectedValue != null && cbxVersionA.SelectedValue != null)
            {
                ServerA.ModelVersion = cbxVersionA.SelectedValue.ToString();
            }
        }
        private void cbxDatabaseA_GotFocus(object sender, RoutedEventArgs e)
        {
            txtServerAChangedValidation();
        }
        
        private void txtServerAChangedValidation()
        {
            if (txtServerAChanged == true)
            {
                cbxModelA.DataContext = null;
                ServerA.Model = "";
                cbxVersionA.DataContext = null;
                ServerA.ModelVersion = "";

                populateDatabase(cbxServerA.Text, cbxDatabaseA);
                txtServerAChanged = false;
                
            }
        }

        private void txtServerBChangedValidation()
        {
            if (txtServerBChanged == true)
            {
                cbxModelB.DataContext = null;
                ServerB.Model = "";
                cbxVersionB.DataContext = null;
                ServerB.ModelVersion = "";

                populateDatabase(cbxServerB.Text, cbxDatabaseB);
                txtServerBChanged = false;
            }
        }

        private void cbxDatabaseB_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbxDatabaseB.SelectedValue != null)
            {
                ServerB.Database = cbxDatabaseB.SelectedValue.ToString();

                cbxVersionB.DataContext = null;
                ServerB.ModelVersion = "";

                populateMode(cbxServerB.Text, cbxDatabaseB.SelectedValue.ToString(), cbxModelB);
            }
        }
        private void cbxModelB_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbxDatabaseB.SelectedValue != null && cbxModelB.SelectedValue != null)
            {
                ServerB.Model = cbxModelB.SelectedValue.ToString();
                populateVersion(cbxServerB.Text, cbxDatabaseB.SelectedValue.ToString(),
                                cbxModelB.SelectedValue.ToString(),
                                cbxVersionB);
            }

        }
        private void cbxVersionB_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbxDatabaseB.SelectedValue != null && cbxModelB.SelectedValue != null && cbxVersionB.SelectedValue != null)
            {
                ServerB.ModelVersion = cbxVersionB.SelectedValue.ToString();
            }
        }
        private void cbxDatabaseB_GotFocus(object sender, RoutedEventArgs e)
        {
            txtServerBChangedValidation();
        }

        private void populateAll(ServerMDSDetails server, ComboBox cbxServer, ComboBox cbxDatabase, ComboBox cbxModel, ComboBox cbxVersion)
        {
            if (server != null && !String.IsNullOrEmpty(server.ServerName))
            {
                cbxServer.SelectedValue = server.ServerName;
                cbxServer.Text = server.ServerName;
                populateDatabase(server.ServerName, cbxDatabase);
                if (!String.IsNullOrEmpty(server.Database))
                {
                    cbxDatabase.SelectedValue = server.Database;
                    populateMode(server.ServerName, server.Database, cbxModel);
                    if (!String.IsNullOrEmpty(server.Model))
                    {
                        cbxModel.SelectedValue = server.Model;
                        if (!String.IsNullOrEmpty(server.ModelVersion))
                        {
                            populateVersion(server.ServerName, server.Database, server.Model, cbxVersion);
                            cbxVersion.SelectedValue = server.ModelVersion;
                        }
                    }
                }
            }

        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            using (new WaitCursor())
            {
                Loading = true;
                populateAll(ServerA, cbxServerA, cbxDatabaseA, cbxModelA, cbxVersionA);
                populateAll(ServerB, cbxServerB, cbxDatabaseB, cbxModelB, cbxVersionB);
                Loading = false;
            }

        }

        private void cbxModelA_GotFocus(object sender, RoutedEventArgs e)
        {
            txtServerAChangedValidation();
        }

        private void cbxVersionA_GotFocus(object sender, RoutedEventArgs e)
        {
            txtServerAChangedValidation();
        }

        private void cbxModelB_GotFocus(object sender, RoutedEventArgs e)
        {
            txtServerBChangedValidation();
        }

        private void cbxVersionB_GotFocus(object sender, RoutedEventArgs e)
        {
            txtServerBChangedValidation();
        }

        private void cbxServerA_LostFocus(object sender, RoutedEventArgs e)
        {
            txtServerAChangedValidation();
        }

        private void cbxServerB_LostFocus(object sender, RoutedEventArgs e)
        {
            txtServerBChangedValidation();
        }

        private void cbxServerA_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                if (Loading == false)
                {
                    txtServerAChanged = true;
                   // txtServerAChangedValidation();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error has occurred", "Error", MessageBoxButton.OK,
                    MessageBoxImage.Error);
                Console.WriteLine("Message:");
                Console.WriteLine(ex.Message);
                Console.WriteLine("Stack Trace:");
                Console.WriteLine(ex.StackTrace);
                Console.WriteLine("Inner Exception:");
                Console.WriteLine(ex.InnerException);
            }
        }

        private void cbxServerB_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
             try
            {
            if (Loading == false)
            {
                txtServerBChanged = true;
             //   txtServerBChangedValidation();
            }
            }
             catch (Exception ex)
             {
                 MessageBox.Show("An error has occurred", "Error", MessageBoxButton.OK,
                     MessageBoxImage.Error);
                 Console.WriteLine("Message:");
                 Console.WriteLine(ex.Message);
                 Console.WriteLine("Stack Trace:");
                 Console.WriteLine(ex.StackTrace);
                 Console.WriteLine("Inner Exception:");
                 Console.WriteLine(ex.InnerException);
             }
        }

        private void cbxUseSameAsServerA_Checked(object sender, RoutedEventArgs e)
        {

            ServerB.ServerName = ServerA.ServerName;
            ServerB.Database = ServerA.Database;
            ServerB.Model = ServerA.Model;
            ServerB.ModelVersion = ServerA.ModelVersion;
            ServerB.schemaVersion = ServerA.schemaVersion;

            Loading = true;
            populateAll(ServerA, cbxServerB, cbxDatabaseB, cbxModelB, cbxVersionB);
            Loading = false;
            
            cbxServerB.IsEnabled = false;
            cbxDatabaseB.IsEnabled = false;
            cbxModelB.IsEnabled = false;
            cbxVersionB.IsEnabled = false;
        }

        private void cbxUseSameAsServerA_Unchecked(object sender, RoutedEventArgs e)
        {
            cbxServerB.IsEnabled = true;
            cbxDatabaseB.IsEnabled = true;
            cbxModelB.IsEnabled = true;
            cbxVersionB.IsEnabled = true;
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (this.DialogResult == null || this.DialogResult != true)
            {
                if (!isCancel)
                {
                    if (String.IsNullOrEmpty(cbxServerA.Text) || String.IsNullOrEmpty(cbxServerB.Text))
                    {
                        e.Cancel = true;
                        MessageBox.Show("Server details are missing", "Warning", MessageBoxButton.OK,
                            MessageBoxImage.Exclamation);
                        return;
                    }

                    if (cbxDatabaseA.SelectedValue == null || cbxDatabaseB.SelectedValue == null ||
                        String.IsNullOrEmpty(cbxDatabaseA.SelectedValue.ToString()) ||
                        String.IsNullOrEmpty(cbxDatabaseB.SelectedValue.ToString()))
                    {
                        e.Cancel = true;
                        MessageBox.Show("Database details are missing", "Warning", MessageBoxButton.OK,
                            MessageBoxImage.Exclamation);
                        return;
                    }

                    if (cbxModelA.SelectedValue == null || cbxModelB.SelectedValue == null ||
                        String.IsNullOrEmpty(cbxModelA.SelectedValue.ToString()) ||
                        String.IsNullOrEmpty(cbxModelB.SelectedValue.ToString()))
                    {
                        e.Cancel = true;
                        MessageBox.Show("Model details are missing", "Warning", MessageBoxButton.OK,
                            MessageBoxImage.Exclamation);
                        return;
                    }

                    if (cbxVersionA.SelectedValue == null || cbxVersionB.SelectedValue == null ||
                        String.IsNullOrEmpty(cbxVersionA.SelectedValue.ToString()) ||
                        String.IsNullOrEmpty(cbxVersionB.SelectedValue.ToString()))
                    {
                        e.Cancel = true;
                        MessageBox.Show("Version details are missing", "Warning", MessageBoxButton.OK,
                            MessageBoxImage.Exclamation);
                        return;
                    }
                }
                CancelConnectionConfig();
            }
        }

    }
}
